// vim:ft=javascript

function mongodb_generate_header(inpath, outpath, replacements)
{
  STDOUT.WriteLine("Generating " + outpath);

  var infile = FSO.OpenTextFile(inpath, 1);
  var outdata = infile.ReadAll();
  infile.Close();

  for (var key in replacements) {
    var replacement = replacements[key];

    if (typeof replacement === 'string') {
      replacement = replacement.replace(/"/g, '\\"');
    }

    outdata = outdata.replace(new RegExp('@' + key + '@', 'g'), replacement);
  }

  var outfile = FSO.CreateTextFile(outpath, true);
  outfile.Write(outdata);
  outfile.Close();
}

function mongodb_parse_libmongoc_version_file(prefix)
{
  var infile = FSO.OpenTextFile(configure_module_dirname + "/src/libmongoc/VERSION_CURRENT", 1);
  var version = infile.ReadLine();
  infile.Close();

  var xyz_pre = version.split("-");
  var xyz = xyz_pre[0].split(".");
  var pre = xyz_pre.length > 1 ? xyz_pre[1] : "";

  var replacements = {};
  replacements[prefix + "VERSION_FULL"] = version;
  replacements[prefix + "VERSION_MAJOR"] = xyz[0];
  replacements[prefix + "VERSION_MINOR"] = xyz[1];
  replacements[prefix + "VERSION_PATCH"] = xyz[2];
  replacements[prefix + "VERSION_PRERELEASE"] = pre;

  return replacements;
}

function mongodb_get_libmongocrypt_version()
{
  var infile = FSO.OpenTextFile(configure_module_dirname + "/src/LIBMONGOCRYPT_VERSION_CURRENT", 1);
  var version = infile.ReadLine();
  infile.Close();

  return version;
}

function create_folder_recursive(path)
{
    if (FSO.FolderExists(path)) {
      return;
    }

    create_folder_recursive(FSO.GetParentFolderName(path));
    FSO.CreateFolder(path);
}

function MONGODB_ADD_SOURCES(dir, file_list)
{
  // Ensure obj_dir and all parent directories exist
  create_folder_recursive(FSO.BuildPath(get_define('BUILD_DIR'), dir));
  ADD_SOURCES(configure_module_dirname + dir, file_list, "mongodb", dir);
}

ARG_ENABLE("mongodb", "MongoDB support", "no");
ARG_WITH("mongodb-sasl", "MongoDB: Build with SSPI SASL (valid values: 'yes' (fallback to SSPI), 'sspi', 'no')", "yes");
ARG_WITH("mongodb-client-side-encryption", "MongoDB: Enable client-side encryption", "yes");

if (PHP_MONGODB != "no") {
  ADD_EXTENSION_DEP("mongodb", "date", false);
  ADD_EXTENSION_DEP("mongodb", "standard", false);
  ADD_EXTENSION_DEP("mongodb", "json", false);
  ADD_EXTENSION_DEP("mongodb", "spl", false);

  /* MongoDB does not actually depend on PHP's OpenSSL extension, but this is in
   * place to ensure that later SSL library checks succeed. This can be removed
   * once we support building with Secure Channel. */
  ADD_EXTENSION_DEP("mongodb", "openssl", false);

  var PHP_MONGODB_CFLAGS="\
    /D BSON_COMPILATION /D MONGOC_COMPILATION /D UTF8PROC_STATIC \
    /I" + configure_module_dirname + " \
    /I" + configure_module_dirname + "/src \
    /I" + configure_module_dirname + "/src/BSON \
    /I" + configure_module_dirname + "/src/MongoDB \
    /I" + configure_module_dirname + "/src/MongoDB/Exception \
    /I" + configure_module_dirname + "/src/MongoDB/Monitoring \
    /I" + configure_module_dirname + "/src/contrib \
    /I" + configure_module_dirname + "/src/libmongoc/src/common/src \
    /I" + configure_module_dirname + "/src/libmongoc/src/common/src/mlib \
    /I" + configure_module_dirname + "/src/libmongoc/src/uthash \
    /I" + configure_module_dirname + "/src/libmongoc/src/libbson/src \
    /I" + configure_module_dirname + "/src/libmongoc/src/libbson/src/jsonsl \
    /I" + configure_module_dirname + "/src/libmongoc/src/libmongoc/src \
    /I" + configure_module_dirname + "/src/libmongoc/src/libmongoc/src/mongoc \
    /I" + configure_module_dirname + "/src/libmongoc/src/utf8proc-2.8.0 \
  ";

  // Condense whitespace in CFLAGS
  PHP_MONGODB_CFLAGS = PHP_MONGODB_CFLAGS.replace(/\s+/g, ' ');

  // Sources below are updated by scripts/update-submodule-sources.php
  var PHP_MONGODB_COMMON_SOURCES="common-atomic.c common-b64.c common-json.c common-md5.c common-oid.c common-string.c common-thread.c"
  var PHP_MONGODB_KMS_MESSAGE_SOURCES="hexlify.c kms_azure_request.c kms_b64.c kms_caller_identity_request.c kms_crypto_apple.c kms_crypto_libcrypto.c kms_crypto_none.c kms_crypto_windows.c kms_decrypt_request.c kms_encrypt_request.c kms_gcp_request.c kms_kmip_reader_writer.c kms_kmip_request.c kms_kmip_response.c kms_kmip_response_parser.c kms_kv_list.c kms_message.c kms_port.c kms_request.c kms_request_opt.c kms_request_str.c kms_response.c kms_response_parser.c sort.c";
  var PHP_MONGODB_BSON_SOURCES="bson-bcon.c bson.c bson-clock.c bson-context.c bson-decimal128.c bson-iso8601.c bson-iter.c bson-json.c bson-keys.c bson-oid.c bson-reader.c bson-string.c bson-timegm.c bson-utf8.c bson-value.c bson-vector.c bson-version-functions.c bson-writer.c error.c memory.c validate.c";
  var PHP_MONGODB_JSONSL_SOURCES="jsonsl.c";
  var PHP_MONGODB_MONGOC_SOURCES="mcd-azure.c mcd-nsinfo.c mcd-rpc.c mongoc-aggregate.c mongoc-apm.c mongoc-array.c mongoc-async.c mongoc-async-cmd.c mongoc-buffer.c mongoc-bulk-operation.c mongoc-bulkwrite.c mongoc-change-stream.c mongoc-client.c mongoc-client-pool.c mongoc-client-session.c mongoc-client-side-encryption.c mongoc-cluster-aws.c mongoc-cluster.c mongoc-cluster-cyrus.c mongoc-cluster-sasl.c mongoc-cluster-sspi.c mongoc-cmd.c mongoc-collection.c mongoc-compression.c mongoc-counters.c mongoc-crypt.c mongoc-crypto.c mongoc-crypto-cng.c mongoc-crypto-common-crypto.c mongoc-crypto-openssl.c mongoc-cursor-array.c mongoc-cursor.c mongoc-cursor-change-stream.c mongoc-cursor-cmd.c mongoc-cursor-cmd-deprecated.c mongoc-cursor-find.c mongoc-cursor-find-cmd.c mongoc-cursor-find-opquery.c mongoc-cursor-legacy.c mongoc-cyrus.c mongoc-database.c mongoc-deprioritized-servers.c mongoc-error.c mongoc-find-and-modify.c mongoc-flags.c mongoc-generation-map.c mongoc-gridfs-bucket.c mongoc-gridfs-bucket-file.c mongoc-gridfs.c mongoc-gridfs-file.c mongoc-gridfs-file-list.c mongoc-gridfs-file-page.c mongoc-handshake.c mongoc-host-list.c mongoc-http.c mongoc-init.c mongoc-interrupt.c mongoc-linux-distro-scanner.c mongoc-list.c mongoc-log-and-monitor-private.c mongoc-log.c mongoc-memcmp.c mongoc-ocsp-cache.c mongoc-oidc-callback.c mongoc-oidc-env.c mongoc-opcode.c mongoc-openssl.c mongoc-optional.c mongoc-opts.c mongoc-opts-helpers.c mongoc-queue.c mongoc-rand-cng.c mongoc-rand-common-crypto.c mongoc-rand-openssl.c mongoc-read-concern.c mongoc-read-prefs.c mongoc-rpc.c mongoc-sasl.c mongoc-scram.c mongoc-secure-channel.c mongoc-secure-transport.c mongoc-server-api.c mongoc-server-description.c mongoc-server-monitor.c mongoc-server-stream.c mongoc-set.c mongoc-shared.c mongoc-socket.c mongoc-ssl.c mongoc-sspi.c mongoc-stream-buffered.c mongoc-stream.c mongoc-stream-file.c mongoc-stream-gridfs.c mongoc-stream-gridfs-download.c mongoc-stream-gridfs-upload.c mongoc-stream-socket.c mongoc-stream-tls.c mongoc-stream-tls-openssl-bio.c mongoc-stream-tls-openssl.c mongoc-stream-tls-secure-channel.c mongoc-stream-tls-secure-transport.c mongoc-structured-log.c mongoc-timeout.c mongoc-topology-background-monitoring.c mongoc-topology.c mongoc-topology-description-apm.c mongoc-topology-description.c mongoc-topology-scanner.c mongoc-ts-pool.c mongoc-uri.c mongoc-util.c mongoc-version-functions.c mongoc-write-command.c mongoc-write-concern.c service-gcp.c";
  var PHP_MONGODB_UTF8PROC_SOURCES="utf8proc.c";

  EXTENSION("mongodb", "php_phongo.c", null, PHP_MONGODB_CFLAGS);
  MONGODB_ADD_SOURCES("/src", "phongo_apm.c phongo_atomic.c phongo_bson.c phongo_bson_encode.c phongo_client.c phongo_compat.c phongo_error.c phongo_execute.c phongo_ini.c phongo_log.c phongo_util.c");
  MONGODB_ADD_SOURCES("/src/BSON", "Binary.c BinaryInterface.c Document.c Iterator.c DBPointer.c Decimal128.c Decimal128Interface.c Int64.c Javascript.c JavascriptInterface.c MaxKey.c MaxKeyInterface.c MinKey.c MinKeyInterface.c ObjectId.c ObjectIdInterface.c PackedArray.c Persistable.c Regex.c RegexInterface.c Serializable.c Symbol.c Timestamp.c TimestampInterface.c Type.c Undefined.c Unserializable.c UTCDateTime.c UTCDateTimeInterface.c VectorType.c");
  MONGODB_ADD_SOURCES("/src/MongoDB", "BulkWrite.c BulkWriteCommand.c BulkWriteCommandResult.c ClientEncryption.c Command.c Cursor.c CursorInterface.c Manager.c Query.c ReadConcern.c ReadPreference.c Server.c ServerApi.c ServerDescription.c Session.c TopologyDescription.c WriteConcern.c WriteConcernError.c WriteError.c WriteResult.c");
  MONGODB_ADD_SOURCES("/src/MongoDB/Exception", "AuthenticationException.c BulkWriteException.c BulkWriteCommandException.c CommandException.c ConnectionException.c ConnectionTimeoutException.c EncryptionException.c Exception.c ExecutionTimeoutException.c InvalidArgumentException.c LogicException.c RuntimeException.c ServerException.c UnexpectedValueException.c");
  MONGODB_ADD_SOURCES("/src/MongoDB/Monitoring", "CommandFailedEvent.c CommandStartedEvent.c CommandSubscriber.c CommandSucceededEvent.c LogSubscriber.c SDAMSubscriber.c Subscriber.c ServerChangedEvent.c ServerClosedEvent.c ServerHeartbeatFailedEvent.c ServerHeartbeatStartedEvent.c ServerHeartbeatSucceededEvent.c ServerOpeningEvent.c TopologyChangedEvent.c TopologyClosedEvent.c TopologyOpeningEvent.c functions.c");
  MONGODB_ADD_SOURCES("/src/libmongoc/src/common/src", PHP_MONGODB_COMMON_SOURCES);
  MONGODB_ADD_SOURCES("/src/libmongoc/src/libbson/src/bson", PHP_MONGODB_BSON_SOURCES);
  MONGODB_ADD_SOURCES("/src/libmongoc/src/libbson/src/jsonsl", PHP_MONGODB_JSONSL_SOURCES);
  MONGODB_ADD_SOURCES("/src/libmongoc/src/libmongoc/src/mongoc", PHP_MONGODB_MONGOC_SOURCES);
  MONGODB_ADD_SOURCES("/src/libmongoc/src/utf8proc-2.8.0", PHP_MONGODB_UTF8PROC_SOURCES);

  var bson_opts = {
    BSON_BYTE_ORDER: 1234,
    BSON_OS: 2,
    BSON_HAVE_STDBOOL_H: 0,
    BSON_HAVE_STRINGS_H: 0,
    BSON_HAVE_CLOCK_GETTIME: 0,
    BSON_HAVE_STRNLEN: 0,
    BSON_HAVE_SNPRINTF: 0,
    BSON_HAVE_STRLCPY: 0,
    BSON_HAVE_TIMESPEC: 0,
    BSON_HAVE_GMTIME_R: 0,
    BSON_HAVE_RAND_R: 0,
    BSON_HAVE_ALIGNED_ALLOC: 0
  };

  mongodb_generate_header(
    configure_module_dirname + "/src/libmongoc/src/libbson/src/bson/config.h.in",
    configure_module_dirname + "/src/libmongoc/src/libbson/src/bson/config.h",
    bson_opts
  );

  mongodb_generate_header(
    configure_module_dirname + "/src/libmongoc/src/libbson/src/bson/version.h.in",
    configure_module_dirname + "/src/libmongoc/src/libbson/src/bson/version.h",
    mongodb_parse_libmongoc_version_file("libbson_")
  );

  var mongoc_opts = {
    // TODO: Support building with Secure Channel on Windows
    MONGOC_ENABLE_SSL_SECURE_CHANNEL: 0,
    MONGOC_ENABLE_CRYPTO_CNG: 0,
    MONGOC_HAVE_BCRYPT_PBKDF2: 0,
    // Secure Transport does not apply to Windows
    MONGOC_ENABLE_SSL_SECURE_TRANSPORT: 0,
    MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO: 0,
    MONGOC_ENABLE_SSL_OPENSSL: 0,
    MONGOC_ENABLE_CRYPTO_LIBCRYPTO: 0,
    MONGOC_ENABLE_SSL: 0,
    MONGOC_ENABLE_CRYPTO: 0,
    MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE: 0,
    MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION: 0,
    MONGOC_ENABLE_COMPRESSION_SNAPPY: 0,
    MONGOC_ENABLE_COMPRESSION_ZLIB: 0,
    MONGOC_ENABLE_COMPRESSION_ZSTD: 0,
    MONGOC_ENABLE_COMPRESSION: 0,
    MONGOC_ENABLE_DEBUG_ASSERTIONS: 0,
    MONGOC_ENABLE_MONGODB_AWS_AUTH: 0,
    MONGOC_ENABLE_SASL: 0,
    MONGOC_ENABLE_SASL_CYRUS: 0,
    MONGOC_ENABLE_SASL_SSPI: 0,
    MONGOC_ENABLE_SRV: 0,
    MONGOC_ENABLE_RDTSCP: 0,
    MONGOC_ENABLE_SHM_COUNTERS: 0,
    MONGOC_HAVE_ASN1_STRING_GET0_DATA: 0,
    MONGOC_HAVE_SASL_CLIENT_DONE: 0,
    MONGOC_HAVE_SCHED_GETCPU: 0,
    MONGOC_HAVE_SOCKLEN: 1,
    MONGOC_SOCKET_ARG2: "struct sockaddr",
    MONGOC_SOCKET_ARG3: "socklen_t",
    MONGOC_TRACE: 1,
    MONGOC_HAVE_DNSAPI: 0,
    MONGOC_HAVE_RES_NSEARCH: 0,
    MONGOC_HAVE_RES_NDESTROY: 0,
    MONGOC_HAVE_RES_NCLOSE: 0,
    MONGOC_HAVE_RES_SEARCH: 0,
    MONGOC_HAVE_SS_FAMILY: 0,
    MONGOC_CC: "",
    MONGOC_USER_SET_CFLAGS: "",
    MONGOC_USER_SET_LDFLAGS: ""
  };

  var mongoc_ssl_path_to_check = PHP_MONGODB;

  if (typeof PHP_OPENSSL === 'string') {
    mongoc_ssl_path_to_check += ";" + PHP_OPENSSL;
  }

  var mongoc_ssl_found = false;

  /* PHP 7.1.2 introduced SETUP_OPENSSL(), which supports OpenSSL 1.1.x. Earlier
   * versions will use the legacy check for OpenSSL 1.0.x and lower. */
  if (typeof SETUP_OPENSSL === 'function') {
    openssl_type = SETUP_OPENSSL("mongodb", mongoc_ssl_path_to_check);
    mongoc_ssl_found = openssl_type > 0;
    if (openssl_type >= 2) {
      mongoc_opts.MONGOC_HAVE_ASN1_STRING_GET0_DATA = 1;
    }
  } else if (CHECK_LIB("ssleay32.lib", "mongodb", mongoc_ssl_path_to_check) &&
             CHECK_LIB("libeay32.lib", "mongodb", mongoc_ssl_path_to_check) &&
             CHECK_LIB("crypt32.lib", "mongodb", mongoc_ssl_path_to_check) &&
             CHECK_HEADER_ADD_INCLUDE("openssl/ssl.h", "CFLAGS_MONGODB")) {
    mongoc_ssl_found = true;
  }

  if (mongoc_ssl_found) {
    mongoc_opts.MONGOC_ENABLE_SSL_OPENSSL = 1;
    mongoc_opts.MONGOC_ENABLE_CRYPTO_LIBCRYPTO = 1;
    mongoc_opts.MONGOC_ENABLE_SSL = 1;
    mongoc_opts.MONGOC_ENABLE_CRYPTO = 1;
    mongoc_opts.MONGOC_ENABLE_MONGODB_AWS_AUTH = 1;

    ADD_FLAG("CFLAGS_MONGODB", "/D KMS_MSG_STATIC=1 /D KMS_MESSAGE_ENABLE_CRYPTO=1 /D KMS_MESSAGE_ENABLE_CRYPTO_LIBCRYPTO=1");
  } else {
    WARNING("mongodb libopenssl support not enabled, libs not found");
  }

  has_sasl_libs = CHECK_LIB("libsasl.lib", "mongodb", PHP_MONGODB) &&
    CHECK_HEADER_ADD_INCLUDE("sasl/sasl.h", "CFLAGS_MONGODB");
  if (PHP_MONGODB_SASL != "no") {
    if (has_sasl_libs) {
      // TODO 3.0: Remove warning on "yes" as it implies "sspi"
      if (PHP_MONGODB_SASL == "yes") {
        WARNING("Cyrus SASL support for Windows was removed. Falling back to SSPI; use '--with-mongodb-sasl=sspi' to avoid this warning.");
        PHP_MONGODB_SASL = "sspi";
      }

      if (PHP_MONGODB_SASL == "sspi") {
        mongoc_opts.MONGOC_ENABLE_SASL = 1;
        mongoc_opts.MONGOC_ENABLE_SASL_SSPI = 1;
      } else {
        ERROR("MongoDB SASL support not enabled, unknown value for --with-mongodb-sasl: " + PHP_MONGODB_SASL);
      }

      if (CHECK_FUNC_IN_HEADER("sasl/sasl.h", "sasl_client_done")) {
        mongoc_opts.MONGOC_HAVE_SASL_CLIENT_DONE = 1;
      }
    } else if (PHP_MONGODB_SASL != "yes") {
      // If the user explicitly requested SASL support, we error out if the
      // necessary libraries are not found.
      ERROR("MongoDB SASL support not enabled, libs not found");
    } else {
      WARNING("MongoDB SASL support not enabled, libs not found");
    }
  }

  if (PHP_MONGODB_CLIENT_SIDE_ENCRYPTION != "no" && mongoc_ssl_found) {
    mongoc_opts.MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION = 1;

    ADD_FLAG("CFLAGS_MONGODB", "/D KMS_MESSAGE_LITTLE_ENDIAN=1 /D MONGOCRYPT_LITTLE_ENDIAN=1 /D MLIB_USER=1");
    ADD_FLAG("CFLAGS_MONGODB", "/I" + configure_module_dirname + "/src/libmongocrypt/src");
    ADD_FLAG("CFLAGS_MONGODB", "/I" + configure_module_dirname + "/src/libmongocrypt/kms-message/src");
    ADD_FLAG("CFLAGS_MONGODB", "/I" + configure_module_dirname + "/src/libmongocrypt-compat");

    var mongocrypt_opts = {
      MONGOCRYPT_ENABLE_TRACE: 1,
      MONGOCRYPT_ENABLE_CRYPTO: 1,
      MONGOCRYPT_ENABLE_CRYPTO_LIBCRYPTO: 1,
      // TODO: Support building with Secure Channel on Windows
      MONGOCRYPT_ENABLE_CRYPTO_CNG: 0,
      // Secure Transport does not apply to Windows
      MONGOCRYPT_ENABLE_CRYPTO_COMMON_CRYPTO: 0
    };

    // Sources below are updated by scripts/update-submodule-sources.php
    var PHP_MONGODB_MONGOCRYPT_SOURCES="mc-array.c mc-efc.c mc-fle2-encryption-placeholder.c mc-fle2-find-equality-payload.c mc-fle2-find-equality-payload-v2.c mc-fle2-find-range-payload.c mc-fle2-find-range-payload-v2.c mc-fle2-find-text-payload.c mc-fle2-insert-update-payload.c mc-fle2-insert-update-payload-v2.c mc-fle2-payload-iev.c mc-fle2-payload-iev-v2.c mc-fle2-payload-uev.c mc-fle2-payload-uev-common.c mc-fle2-payload-uev-v2.c mc-fle2-rfds.c mc-fle2-tag-and-encrypted-metadata-block.c mc-parse-utils.c mc-range-edge-generation.c mc-range-encoding.c mc-range-mincover.c mc-rangeopts.c mc-reader.c mc-schema-broker.c mc-str-encode-string-sets.c mc-textopts.c mc-text-search-str-encode.c mc-tokens.c mc-writer.c mongocrypt-binary.c mongocrypt-buffer.c mongocrypt.c mongocrypt-cache.c mongocrypt-cache-collinfo.c mongocrypt-cache-key.c mongocrypt-cache-oauth.c mongocrypt-ciphertext.c mongocrypt-crypto.c mongocrypt-ctx.c mongocrypt-ctx-datakey.c mongocrypt-ctx-decrypt.c mongocrypt-ctx-encrypt.c mongocrypt-ctx-rewrap-many-datakey.c mongocrypt-endpoint.c mongocrypt-kek.c mongocrypt-key-broker.c mongocrypt-key.c mongocrypt-kms-ctx.c mongocrypt-log.c mongocrypt-marking.c mongocrypt-opts.c mongocrypt-status.c mongocrypt-traverse-util.c mongocrypt-util.c";
    var PHP_MONGODB_MONGOCRYPT_CRYPTO_SOURCES="cng.c commoncrypto.c libcrypto.c none.c";
    var PHP_MONGODB_MONGOCRYPT_OS_POSIX_SOURCES="os_dll.c os_mutex.c";
    var PHP_MONGODB_MONGOCRYPT_OS_WIN_SOURCES="os_dll.c os_mutex.c";
    var PHP_MONGODB_MONGOCRYPT_UNICODE_SOURCES="case-fold-map.c diacritic-fold-map.c fold.c";
    var PHP_MONGODB_MONGOCRYPT_KMS_MESSAGE_SOURCES="hexlify.c kms_azure_request.c kms_b64.c kms_caller_identity_request.c kms_crypto_apple.c kms_crypto_libcrypto.c kms_crypto_none.c kms_crypto_windows.c kms_decrypt_request.c kms_encrypt_request.c kms_gcp_request.c kms_kmip_reader_writer.c kms_kmip_request.c kms_kmip_response.c kms_kmip_response_parser.c kms_kv_list.c kms_message.c kms_port.c kms_request.c kms_request_opt.c kms_request_str.c kms_response.c kms_response_parser.c sort.c";

    MONGODB_ADD_SOURCES("/src/libmongocrypt/src", PHP_MONGODB_MONGOCRYPT_SOURCES);
    MONGODB_ADD_SOURCES("/src/libmongocrypt/src/crypto", PHP_MONGODB_MONGOCRYPT_CRYPTO_SOURCES);
    MONGODB_ADD_SOURCES("/src/libmongocrypt/src/os_posix", PHP_MONGODB_MONGOCRYPT_OS_POSIX_SOURCES);
    MONGODB_ADD_SOURCES("/src/libmongocrypt/src/os_win", PHP_MONGODB_MONGOCRYPT_OS_WIN_SOURCES);
    MONGODB_ADD_SOURCES("/src/libmongocrypt/src/unicode", PHP_MONGODB_MONGOCRYPT_UNICODE_SOURCES);
    MONGODB_ADD_SOURCES("/src/libmongocrypt/kms-message/src", PHP_MONGODB_MONGOCRYPT_KMS_MESSAGE_SOURCES);

    mongocrypt_opts.MONGOCRYPT_BUILD_VERSION = mongodb_get_libmongocrypt_version();

    mongodb_generate_header(
      configure_module_dirname + "/src/libmongocrypt/src/mongocrypt-config.h.in",
      configure_module_dirname + "/src/libmongocrypt/src/mongocrypt-config.h",
      mongocrypt_opts
    );
  } else if (PHP_MONGODB_CLIENT_SIDE_ENCRYPTION != "no") {
    // No SSL library found, we can't enable libmongocrypt
    WARNING("mongodb libmongocrypt support not enabled, crypto libs not found");
  }

  if (PHP_MONGODB_CLIENT_SIDE_ENCRYPTION == "no" && mongoc_ssl_found) {
    // Add kms-message sources bundled with libmongoc
    MONGODB_ADD_SOURCES("/src/libmongoc/src/kms-message/src", PHP_MONGODB_KMS_MESSAGE_SOURCES);
    ADD_FLAG("CFLAGS_MONGODB", "/I" + configure_module_dirname + "/src/libmongoc/src/kms-message/src");
  }

  if (CHECK_LIB("dnsapi.lib", "mongodb", PHP_MONGODB) &&
      CHECK_HEADER_ADD_INCLUDE("windns.h", "CFLAGS_MONGODB")) {
    mongoc_opts.MONGOC_HAVE_DNSAPI = 1;
    mongoc_opts.MONGOC_ENABLE_SRV = 1;
  }

  if (typeof COMPILER_NAME === 'string') {
    mongoc_opts.MONGOC_CC = COMPILER_NAME;
  } else if (typeof VC_VERSIONS === 'array' && typeof VC_VERSIONS[VCVERS] === 'string') {
    mongoc_opts.MONGOC_CC = VC_VERSIONS[VCVERS];
  } else if (typeof COMPILER_NAME_LONG === 'string') {
    mongoc_opts.MONGOC_CC = COMPILER_NAME_LONG;
  }

  /* MONGOC_USER_SET_CFLAGS and MONGOC_USER_SET_LDFLAGS can be left blank, as we
   * do not expect CFLAGS or LDFLAGS to be customized at build time. */

  mongodb_generate_header(
    configure_module_dirname + "/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h.in",
    configure_module_dirname + "/src/libmongoc/src/libmongoc/src/mongoc/mongoc-config.h",
    mongoc_opts
  );

  mongodb_generate_header(
    configure_module_dirname + "/src/libmongoc/src/common/src/common-config.h.in",
    configure_module_dirname + "/src/libmongoc/src/common/src/common-config.h",
    mongoc_opts
  );

  mongodb_generate_header(
    configure_module_dirname + "/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h.in",
    configure_module_dirname + "/src/libmongoc/src/libmongoc/src/mongoc/mongoc-version.h",
    mongodb_parse_libmongoc_version_file("libmongoc_")
  );
}
